// Inclusion guard start
#ifndef GAME_ENGINE_H
#define GAME_ENGINE_H

// Include libraries
#include <SDL/SDL.h>
#include <vector.h>
#include <stdio.h>
#include <stdlib.h>
#include "gfx.h"

// Include misc
#include "typedefs.h"
#include "types.h"

// Include game engine parts
#include "character.h"

class GameEngine
{
	// Public
	public:
		// Variables
			// Time
			u32 time;

			// Dimensions
			u32 xSize;
			u32 ySize;

			// Object vectors
				// Characters
				vector<Character*> characterInstances;

				// Terrain parts available
				vector<TerrainPartSpecs> terrainPartsAvailable;

				// Terrain parts positions
				vector<TerrainPartInstance> terrainPartInstances;


		// Functions
		/** @brief Constructor
		  *
		  * @param screen pointer to screen surface
		  */
		GameEngine(SDL_Surface* screen);

		/** @brief Loads a stage
		  *
		  * @param path file path to open
		  *
		  * @return true if load was successful, false otherwise
		  */
		bool loadStage(const char* path);

		/** @brief Makes a terrain part available
		  *
		  * @param x x coordinate of leftmost part of clip
		  * @param y y coordinate of top of clip
		  * @param width width of clip
		  * @param height height of clip
		  */
		void addTerrainPartSpecs(u16 x, u16 y, u16 width, u16 height, BoundingBox* boundingBox);

		/** @brief Adds a terrain part instance
		  *
		  * @param x x cooridinate of the instance
		  * @param y y cooridinate of the instance
		  * @param identifier terrain part identifier
		  */
		void addTerrainPartInstance(s32 x, s32 y, u16 identifier);

		/** @brief Sets tileset
		  *
		  * @param tileset surface pointer to tileset to be set
		  */
		void setTileset(SDL_Surface* tileset);

		/** @brief Draws the contents of the engine to the screen
		  */
		void applyGraphics();

		/** @brief Checks if a boundingbox collides with the terrain
		  *
		  * @param x x coordinate of bounding box
		  * @param y y coordinate of bounding box
		  * @param boundingbox pointer to the boundingbox
		  * @param check what to check collisions with. 0 means check nothing.
		  *
		  * @return bool true if there is a collision, false otherwise
		  */
		bool checkCollision(u16 x, u16 y, BoundingBox* boundingBox, u32 check);

		/** @brief adds a character instance
		  *
		  * @param type type of character
		  * @param x x starting position
		  * @param y y starting position
		  * @param direction starting direction
		  *
		  * @return character identifier
		  */
		u16 addCharacterInstance(CharacterType type, s32 x, s32 y, s16 direction);

		/** @brief iterates all characters
		  */
		void iterateCharacters();

		// Private
		private:
			// Variables
				// Tileset
				SDL_Surface* srf_tileset;

				// Screen surface
				SDL_Surface* srf_screen;
};

/** @brief Calls the checkCollision
  *
  * @param gameEngine game engine to call function with
  * @param x x coordinate of bounding box
  * @param y y coordinate of bounding box
  * @param boundingbox pointer to the boundingbox
  * @param check what to check collisions with. 0 means check nothing.
  *
  * @return bool true if there is a collision, false otherwise
  */
bool gameEngine_checkCollision(GameEngine* gameEngine, u16 x, u16 y, BoundingBox* boundingBox, u32 check);

// Inclusion guard end
#endif
